home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1999 #2 / Amiga Plus CD - 1999 - No. 2.iso / System-Boost / Workbench / ToolManager / Source / Library / menu.c < prev    next >
C/C++ Source or Header  |  1998-06-17  |  10KB  |  360 lines

  1. /*
  2.  * menu.c  V3.1
  3.  *
  4.  * ToolManager Objects Menu class
  5.  *
  6.  * Copyright (C) 1990-98 Stefan Becker
  7.  *
  8.  * This source code is for educational purposes only. You may study it
  9.  * and copy ideas or algorithms from it for your own projects. It is
  10.  * not allowed to use any of the source codes (in full or in parts)
  11.  * in other programs. Especially it is not allowed to create variants
  12.  * of ToolManager or ToolManager-like programs from this source code.
  13.  *
  14.  */
  15.  
  16. #include "toolmanager.h"
  17.  
  18. /* Menu class instance data */
  19. struct MenuClassData {
  20.  ULONG                mcd_Flags;
  21.  void                *mcd_AppObject;
  22.  struct TMMemberData *mcd_ExecObject;
  23.  struct TMMemberData *mcd_SoundObject;
  24. };
  25. #define TYPED_INST_DATA(cl, o) ((struct MenuClassData *) INST_DATA((cl), (o)))
  26.  
  27. /* Menu class method: OM_NEW */
  28. #define DEBUGFUNCTION MenuClassNew
  29. static ULONG MenuClassNew(Class *cl, Object *obj, struct opSet *ops)
  30. {
  31.  MENUCLASS_LOG((LOG1(Tags, "0x%08lx", ops->ops_AttrList),
  32.                 PrintTagList(ops->ops_AttrList)))
  33.  
  34.  /* Call SuperClass */
  35.  if (obj = (Object *) DoSuperMethodA(cl, obj, (Msg) ops)) {
  36.   struct MenuClassData *mcd = TYPED_INST_DATA(cl, obj);
  37.  
  38.   /* Initialize instance data */
  39.   mcd->mcd_Flags       = 0;
  40.   mcd->mcd_AppObject   = NULL;
  41.   mcd->mcd_ExecObject  = NULL;
  42.   mcd->mcd_SoundObject = NULL;
  43.  }
  44.  
  45.  return((ULONG) obj);
  46. }
  47.  
  48. /* Menu class method: OM_DISPOSE */
  49. #undef  DEBUGFUNCTION
  50. #define DEBUGFUNCTION MenuClassDispose
  51. static ULONG MenuClassDispose(Class *cl, Object *obj, Msg msg)
  52. {
  53.  struct MenuClassData *mcd = TYPED_INST_DATA(cl, obj);
  54.  
  55.  MENUCLASS_LOG(LOG0(Disposing))
  56.  
  57.  /* Sound object attached? Release it */
  58.  if (mcd->mcd_SoundObject) DoMethod(mcd->mcd_SoundObject->tmmd_Object,
  59.                                     TMM_Detach, mcd->mcd_SoundObject);
  60.  
  61.  /* Exec object attached? Release it */
  62.  if (mcd->mcd_ExecObject) DoMethod(mcd->mcd_ExecObject->tmmd_Object,
  63.                                    TMM_Detach, mcd->mcd_ExecObject);
  64.  
  65.  /* Remove menu item */
  66.  if (mcd->mcd_AppObject) DeleteAppMenuItem(mcd->mcd_AppObject, obj);
  67.  
  68.  /* Call SuperClass */
  69.  return(DoSuperMethodA(cl, obj, msg));
  70. }
  71.  
  72. /* Menu class method: TMM_Release */
  73. #undef  DEBUGFUNCTION
  74. #define DEBUGFUNCTION MenuClassRelease
  75. static ULONG MenuClassRelease(Class *cl, Object *obj, struct TMP_Detach *tmpd)
  76. {
  77.  struct MenuClassData *mcd = TYPED_INST_DATA(cl, obj);
  78.  
  79.  MENUCLASS_LOG(LOG2(Arguments, "Data 0x%08lx Member 0x%08lx",
  80.                     tmpd->tmpd_MemberData, tmpd->tmpd_MemberData->tmmd_Member))
  81.  
  82.  /* Exec or Sound object deleted? */
  83.  if (mcd->mcd_ExecObject == tmpd->tmpd_MemberData)
  84.   mcd->mcd_ExecObject = NULL;
  85.  else
  86.   mcd->mcd_SoundObject = NULL;
  87.  
  88.  /* Detach object */
  89.  DoMethod(tmpd->tmpd_MemberData->tmmd_Object, TMM_Detach,
  90.           tmpd->tmpd_MemberData);
  91.  
  92.  /* Return 1 to indicate that the method is implemented */
  93.  return(1);
  94. }
  95.  
  96. /* Menu class method: TMM_ParseIFF */
  97. #undef  DEBUGFUNCTION
  98. #define DEBUGFUNCTION MenuClassParseIFF
  99. static ULONG MenuClassParseIFF(Class *cl, Object *obj,
  100.                                struct TMP_ParseIFF *tmppi)
  101. {
  102.  BOOL rc = FALSE;
  103.  
  104.  MENUCLASS_LOG(LOG1(Handle, "0x%08lx", tmppi->tmppi_IFFHandle))
  105.  
  106.  /* Forward method to SuperClass */
  107.  if (DoSuperMethodA(cl, obj, (Msg) tmppi)) {
  108.   struct StoredProperty *sp;
  109.  
  110.   MENUCLASS_LOG(LOG0(FORM TMMO chunk parsed OK))
  111.  
  112.   /* Check for mandatory DATA property */
  113.   if (sp = FindProp(tmppi->tmppi_IFFHandle, ID_TMMO, ID_DATA)) {
  114.    struct MenuClassData *mcd = TYPED_INST_DATA(cl, obj);
  115.    struct MenuDATAChunk *mdc = sp->sp_Data;
  116.  
  117.    MENUCLASS_LOG(LOG2(Data, "Exec 0x%08lx Sound 0x%08lx", mdc->mdc_ExecObject,
  118.                       mdc->mdc_SoundObject))
  119.  
  120.    /* Create menu item */
  121.    if (mcd->mcd_AppObject = CreateAppMenuItem(obj)) {
  122.     struct TMHandle *tmh;
  123.  
  124.     MENUCLASS_LOG(LOG1(AppObject, "0x%08lx", mcd->mcd_AppObject))
  125.  
  126.     /* Get TMHandle */
  127.     GetAttr(TMA_TMHandle, obj, (ULONG *) &tmh);
  128.  
  129.     /* Attach Exec object */
  130.     if (mdc->mdc_ExecObject) {
  131.      Object *execobj;
  132.  
  133.      /* Find exec object */
  134.      if (execobj = FindTypedIDTMObject(tmh, mdc->mdc_ExecObject,
  135.                                        TMOBJTYPE_EXEC)) {
  136.  
  137.       MENUCLASS_LOG(LOG1(Exec, "0x%08lx", execobj))
  138.  
  139.       /* Attach to exec object */
  140.       mcd->mcd_ExecObject = (struct TMMemberData *)
  141.        DoMethod(execobj, TMM_Attach, obj, TMV_Attach_Normal);
  142.  
  143.       MENUCLASS_LOG(LOG1(Exec Data, "0x%08lx", mcd->mcd_ExecObject))
  144.      }
  145.     }
  146.  
  147.     /* Attach sound object */
  148.     if (mdc->mdc_SoundObject) {
  149.      Object *soundobj;
  150.  
  151.      /* Find sound object */
  152.      if (soundobj = FindTypedIDTMObject(tmh, mdc->mdc_SoundObject,
  153.                                         TMOBJTYPE_SOUND)) {
  154.  
  155.       MENUCLASS_LOG(LOG1(Sound, "0x%08lx", soundobj))
  156.  
  157.       /* Attach to sound object */
  158.       mcd->mcd_SoundObject = (struct TMMemberData *)
  159.        DoMethod(soundobj, TMM_Attach, obj, TMV_Attach_Normal);
  160.  
  161.       MENUCLASS_LOG(LOG1(Sound Data, "0x%08lx", mcd->mcd_SoundObject))
  162.      }
  163.     }
  164.  
  165.     /* Configuration data parsed */
  166.     rc = TRUE;
  167.    }
  168.   }
  169.  }
  170.  
  171.  MENUCLASS_LOG(LOG1(Result, "%ld", rc))
  172.  
  173.  return(rc);
  174. }
  175.  
  176. /* Menu class method: TMM_ParseTags */
  177. #undef  DEBUGFUNCTION
  178. #define DEBUGFUNCTION MenuClassParseTags
  179. static ULONG MenuClassParseTags(Class *cl, Object *obj,
  180.                                 struct TMP_ParseTags *tmppt)
  181. {
  182.  struct MenuClassData *mcd = TYPED_INST_DATA(cl, obj);
  183.  BOOL                  rc  = FALSE;
  184.  
  185.  MENUCLASS_LOG((LOG1(Tags, "0x%08lx", tmppt->tmppt_Tags),
  186.                 PrintTagList(tmppt->tmppt_Tags)))
  187.  
  188.  /* Create menu item if not already created */
  189.  if (mcd->mcd_AppObject ||
  190.      (mcd->mcd_AppObject = CreateAppMenuItem(obj))) {
  191.   struct TagItem  *tstate = tmppt->tmppt_Tags;
  192.   struct TagItem  *ti;
  193.   struct TMHandle *tmh;
  194.  
  195.   MENUCLASS_LOG(LOG1(AppObject, "0x%08lx", mcd->mcd_AppObject))
  196.  
  197.   /* Reset error code */
  198.   rc = TRUE;
  199.  
  200.   /* Get TMHandle */
  201.   GetAttr(TMA_TMHandle, obj, (ULONG *) &tmh);
  202.  
  203.   /* Scan tag list */
  204.   while (ti = NextTagItem(&tstate))
  205.  
  206.    /* Which tag? */
  207.    switch (ti->ti_Tag) {
  208.     case TMOP_Exec: {
  209.       Object *newobj;
  210.  
  211.       /* Release old object first */
  212.       if (mcd->mcd_ExecObject) DoMethod(mcd->mcd_ExecObject->tmmd_Object,
  213.                                         TMM_Detach, mcd->mcd_ExecObject);
  214.  
  215.       /* Object name valid and does the object exist? */
  216.       if (ti->ti_Data &&
  217.           (newobj = FindTypedNamedTMObject(tmh, (char *) ti->ti_Data,
  218.                                            TMOBJTYPE_EXEC))) {
  219.  
  220.         MENUCLASS_LOG(LOG1(Exec, "0x%08lx", newobj))
  221.  
  222.         /* Yes, attach new object */
  223.         mcd->mcd_ExecObject = (struct TMMemberData *)
  224.                                DoMethod(newobj, TMM_Attach, obj,
  225.                                         TMV_Attach_Normal);
  226.  
  227.        } else
  228.  
  229.         /* No, clear pointer */
  230.         mcd->mcd_ExecObject = NULL;
  231.  
  232.       MENUCLASS_LOG(LOG1(Exec Attach, "0x%08lx", mcd->mcd_ExecObject))
  233.      }
  234.      break;
  235.  
  236.     case TMOP_Sound: {
  237.       Object *newobj;
  238.  
  239.       /* Release old object first */
  240.       if (mcd->mcd_SoundObject) DoMethod(mcd->mcd_SoundObject->tmmd_Object,
  241.                                          TMM_Detach, mcd->mcd_SoundObject);
  242.  
  243.       /* Object name valid and does the object exist? */
  244.       if (ti->ti_Data &&
  245.           (newobj = FindTypedNamedTMObject(tmh, (char *) ti->ti_Data,
  246.                                            TMOBJTYPE_SOUND))) {
  247.  
  248.         MENUCLASS_LOG(LOG1(Sound, "0x%08lx", newobj))
  249.  
  250.         /* Yes, attach new object */
  251.         mcd->mcd_SoundObject = (struct TMMemberData *)
  252.                                 DoMethod(newobj, TMM_Attach, obj,
  253.                                          TMV_Attach_Normal);
  254.  
  255.        } else
  256.  
  257.         /* No, clear pointer */
  258.         mcd->mcd_SoundObject = NULL;
  259.  
  260.       MENUCLASS_LOG(LOG1(Sound Attach, "0x%08lx", mcd->mcd_SoundObject))
  261.      }
  262.      break;
  263.    }
  264.  }
  265.  
  266.  MENUCLASS_LOG(LOG1(Result, "%ld", rc))
  267.  
  268.  return(rc);
  269. }
  270.  
  271. /* Menu class method: TMM_Activate */
  272. #undef  DEBUGFUNCTION
  273. #define DEBUGFUNCTION MenuClassActivate
  274. static ULONG MenuClassActivate(Class *cl, Object *obj,
  275.                                struct TMP_Activate *tmpa)
  276. {
  277.  struct MenuClassData *mcd = TYPED_INST_DATA(cl, obj);
  278.  
  279.  MENUCLASS_LOG(LOG1(Data, "0x%08lx", tmpa->tmpa_Data))
  280.  
  281.  /* Activate sound object */
  282.  if (mcd->mcd_SoundObject) DoMethod(mcd->mcd_SoundObject->tmmd_Object,
  283.                                     TMM_Activate, NULL);
  284.  
  285.  /* Activate Exec object */
  286.  if (mcd->mcd_ExecObject) DoMethod(mcd->mcd_ExecObject->tmmd_Object,
  287.                                    TMM_Activate, tmpa->tmpa_Data);
  288.  
  289.  /* Return 1 to indicate that the method is implemented */
  290.  return(1);
  291. }
  292.  
  293. /* Menu class dispatcher */
  294. #undef  DEBUGFUNCTION
  295. #define DEBUGFUNCTION MenuClassDispatcher
  296. static __geta4 ULONG MenuClassDispatcher(__A0 Class *cl, __A2 Object *obj,
  297.                                          __A1 Msg msg)
  298. {
  299.  ULONG rc;
  300.  
  301.  MENUCLASS_LOG(LOG3(Arguments, "Class 0x%08lx Object 0x%08lx Msg 0x%08lx",
  302.                     cl, obj, msg))
  303.  
  304.  switch(msg->MethodID) {
  305.   /* BOOPSI methods */
  306.   case OM_NEW:
  307.    rc = MenuClassNew(cl, obj, (struct opSet *) msg);
  308.    break;
  309.  
  310.   case OM_DISPOSE:
  311.    rc = MenuClassDispose(cl, obj, msg);
  312.    break;
  313.  
  314.   /* TM methods */
  315.   case TMM_Release:
  316.    rc = MenuClassRelease(cl, obj, (struct TMP_Detach *) msg);
  317.    break;
  318.  
  319.   case TMM_ParseIFF:
  320.    rc = MenuClassParseIFF(cl, obj, (struct TMP_ParseIFF *) msg);
  321.    break;
  322.  
  323.   case TMM_ParseTags:
  324.    rc = MenuClassParseTags(cl, obj, (struct TMP_ParseTags *) msg);
  325.    break;
  326.  
  327.   case TMM_Activate:
  328.    rc = MenuClassActivate(cl, obj, (struct TMP_Activate *) msg);
  329.    break;
  330.  
  331.   /* Unknown method -> delegate to SuperClass */
  332.   default:
  333.    rc = DoSuperMethodA(cl, obj, msg);
  334.    break;
  335.  }
  336.  
  337.  return(rc);
  338. }
  339.  
  340. /* Create Menu class */
  341. #undef  DEBUGFUNCTION
  342. #define DEBUGFUNCTION CreateMenuClass
  343. Class *CreateMenuClass(Class *superclass)
  344. {
  345.  Class *cl;
  346.  
  347.  MENUCLASS_LOG(LOG1(SuperClass, "0x%08lx", superclass))
  348.  
  349.  /* Create class */
  350.  if (cl = MakeClass(NULL, NULL, superclass, sizeof(struct MenuClassData), 0))
  351.  
  352.   /* Set dispatcher */
  353.   cl->cl_Dispatcher.h_Entry = (ULONG (*)()) MenuClassDispatcher;
  354.  
  355.  MENUCLASS_LOG(LOG1(Class, "0x%08lx", cl))
  356.  
  357.  /* Return pointer to class */
  358.  return(cl);
  359. }
  360.